package com.guigu.pd.auth.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guigu.common.utils.PageUtils;
import com.guigu.common.utils.Query;

import com.guigu.pd.auth.dao.CoreOrgDao;
import com.guigu.pd.auth.entity.CoreOrgEntity;
import com.guigu.pd.auth.service.CoreOrgService;


@Service("coreOrgService")
public class CoreOrgServiceImpl extends ServiceImpl<CoreOrgDao, CoreOrgEntity> implements CoreOrgService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CoreOrgEntity> page = this.page(
                new Query<CoreOrgEntity>().getPage(params),
                new QueryWrapper<CoreOrgEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CoreOrgEntity> listWithTree(Map<String, Object> params) {
        CoreOrgEntity mapCoreOrg = JSON.parseObject(JSON.toJSONString(params), CoreOrgEntity.class);

        if (StringUtils.isNotBlank(mapCoreOrg.getName())) {
            LambdaQueryWrapper<CoreOrgEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.like(StringUtils.isNotBlank(mapCoreOrg.getName()), CoreOrgEntity::getName, mapCoreOrg.getName());
            List<CoreOrgEntity> entityChildren = baseMapper.selectList(queryWrapper);

            List<CoreOrgEntity> coreOrgEntityList = entityChildren.stream().map(menu -> {
                menu.setChildren(getChildrens(menu));
                return getParent(menu);
            }).collect(Collectors.toList());
            // TODO 递归问题
            return coreOrgEntityList;
        } else {
            List<CoreOrgEntity> entities = baseMapper.selectList(null);

            List<CoreOrgEntity> leve1Menus = entities.stream().filter(
                    coreOrgEntity -> coreOrgEntity.getParentId() == 0
            ).map(menu -> {
                menu.setChildren(getChildren(menu, entities));
                return menu;
            }).sorted(
                    Comparator.comparingInt(menu -> (menu.getSortValue() == null ? 0 : menu.getSortValue()))
            ).collect(Collectors.toList());

            return leve1Menus;
        }
    }

    /**
     * 递归查找所有菜单的子菜单
     */
    private List<CoreOrgEntity> getChildren(CoreOrgEntity root, List<CoreOrgEntity> all) {
        List<CoreOrgEntity> children = all.stream().
                filter(coreOrgEntity -> coreOrgEntity.getParentId().equals(root.getId())).map(coreOrgEntity -> {
                    coreOrgEntity.setChildren(getChildren(coreOrgEntity, all));
                    return coreOrgEntity;
                }).sorted(
                        Comparator.comparingInt(menu -> (menu.getSortValue() == null ? 0 : menu.getSortValue()))).collect(Collectors.toList()
                );
        return children;
    }

    private List<CoreOrgEntity> getChildrens(CoreOrgEntity root) {

        LambdaQueryWrapper<CoreOrgEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(root.getId().toString()), CoreOrgEntity::getParentId, root.getId());
        List<CoreOrgEntity> menuEntities = baseMapper.selectList(queryWrapper);

        List<CoreOrgEntity> leveChildren = menuEntities.stream().map(menu -> {
            menu.setChildren(getChildrens(menu));
            return menu;
        }).collect(Collectors.toList());

        return leveChildren;
    }

    public CoreOrgEntity getParent(CoreOrgEntity coreOrg) {

        CoreOrgEntity coreOrgEntity = new CoreOrgEntity();
        List<CoreOrgEntity> coreOrgEntities = new ArrayList<>();
        coreOrgEntities.add(coreOrg);

        LambdaQueryWrapper<CoreOrgEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(coreOrg.getParentId().toString()), CoreOrgEntity::getId, coreOrg.getParentId());
        coreOrgEntity = baseMapper.selectOne(queryWrapper);

        coreOrgEntity.setChildren(coreOrgEntities);

        return coreOrgEntity;
    }
}
